<html>
<head>
<script src="../../../resources/js-test.js"></script>
</head>
<body>
<script>
description("Test window.postMessage() argument handling.");

self.jsTestIsAsync = true;

if (window.testRunner) {
    testRunner.dumpAsText();
    testRunner.waitUntilDone();
}

function onmessage(evt) {
    if (evt.ports)
        debug("Received message '" + evt.data + "' with " + evt.ports.length + " ports.");
    else
        debug("Received message '" + evt.data);

    if (evt.data == 'done')
        finishJSTest();
}

window.addEventListener('message', onmessage, false);

function convertDetached(obj) {
    if (obj instanceof Int8Array && obj.byteLength === 0)
        return "[detached TypedArray]";
    return obj;
}

function convertArrayDetached(obj) {
    if (obj instanceof Array)
        return obj.map(convertDetached)
    return obj;
}

function tryPostMessageFunction(postMessageFunction, first, second, third, shouldFail) {
    var pass, reason;
    try {
        postMessageFunction(first, second, third);
        pass = !shouldFail;
        reason = " did not throw an exception";
    } catch (e) {
        pass = shouldFail;
        reason = ": threw exception " + e;
    }
    if (pass)
        testPassed("Posting message ('" + convertDetached(first) + "', " + convertArrayDetached(third) + ")" + reason);
    else
        testFailed("Posting message ('" + convertDetached(first) + "', " + convertArrayDetached(third) + ")" + reason);
}

function tryPostMessage(first, second, third, shouldFail) {
    tryPostMessageFunction(window.postMessage, first, second, third, shouldFail);
}

document.getElementById("description").innerHTML = "Test that the second argument of window.postMessage is ignored or triggers an error if it is not a message port. You should see PASS message '1' through '7', followed by 'done', with messages 4-7 received below.<br><br>";

tryPostMessage('1', '*', 1, true);
tryPostMessage('2', '*', 'c', true);
tryPostMessage('3', '*', { x: 1 }, true);
tryPostMessage('4', '*', window, true);
tryPostMessage('5', '*', undefined);
tryPostMessage('5a', '*', null, true);
tryPostMessage('6', '*', void 0);
var channel1 = new MessageChannel;
tryPostMessageFunction(window.postMessage, '7', '*', [channel1.port1, channel1.port2]);
var channel2 = new MessageChannel;
tryPostMessageFunction(window.postMessage, '7', '*', [channel2.port1, channel2.port2]);
var channel3 = new MessageChannel;
tryPostMessage(2147483648, '*', undefined);
tryPostMessage(2147483648, '*', null, true);
tryPostMessageFunction(window.postMessage, channel3.port1, '*', [channel3.port1, channel3.port2]);
var channel4 = new MessageChannel;
tryPostMessageFunction(window.postMessage, channel4.port1, '*', [channel4.port1, channel4.port2]);
var channel5 = new MessageChannel;
tryPostMessageFunction(window.postMessage, [channel5.port1, channel5.port2], '*', [channel5.port1, channel5.port2]);
tryPostMessageFunction(window.postMessage, 'data', '*', [channel5.port1, channel5.port2], true);
tryPostMessageFunction(window.postMessage, [channel5.port1, channel5.port2], '*', [], true);

var arrayBuffer = new ArrayBuffer(30);
var int8View = new Int8Array(arrayBuffer, 2, 10);
tryPostMessageFunction(window.postMessage, arrayBuffer, '*', [arrayBuffer]);
if (!(arrayBuffer.byteLength === 0))
    testFailed("arrayBuffer not detached; byteLength = " + arrayBuffer.byteLength);
else
    testPassed("arrayBuffer detached");

if (!(int8View.length == 0))
    testFailed("view was not detached; length = " + int8View.length);
else
    testPassed("view detached");

tryPostMessageFunction(window.postMessage, arrayBuffer, '*', [], true);
tryPostMessageFunction(window.postMessage, 'data', '*', [arrayBuffer], true);

tryPostMessageFunction(window.postMessage, int8View, '*', [], true);
tryPostMessageFunction(window.postMessage, 'data', '*', [int8View], true);

tryPostMessageFunction(window.postMessage, 'data', '*', {length:1}, true);
tryPostMessageFunction(window.postMessage, 'data', '*', [1,,2], true);
tryPostMessageFunction(window.postMessage, 'data', '*', [null, window.postMessage], true);

shouldThrow("window.postMessage()");

tryPostMessageFunction(window.postMessage, 'a', undefined, undefined, true);
tryPostMessageFunction(window.postMessage, 'done', '*');
</script>
</body>
</html>
